package org.yunai.swjg.server.core.heartbeat;

import org.slf4j.Logger;
import org.yunai.swjg.server.core.config.GameServerConfig;
import org.yunai.swjg.server.core.config.SharedConstants;
import org.yunai.swjg.server.module.arena.ArenaRunner;
import org.yunai.swjg.server.module.arena.ArenaService;
import org.yunai.swjg.server.module.idSequence.persistance.IdSequenceDataUpdater;
import org.yunai.swjg.server.module.rep.RepScene;
import org.yunai.swjg.server.module.rep.RepSceneService;
import org.yunai.swjg.server.module.scene.NormalScene;
import org.yunai.swjg.server.module.scene.NormalSceneService;
import org.yunai.swjg.server.module.scene.core.AbstractScene;
import org.yunai.swjg.server.module.scene.core.SceneRunner;
import org.yunai.yfserver.common.LoggerFactory;
import org.yunai.yfserver.server.NamedThreadFactory;
import org.yunai.yfserver.spring.BeanManager;
import org.yunai.yfserver.time.TimeService;
import org.yunai.yfserver.util.ExecutorUtils;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * 心跳线程
 * User: yunai
 * Date: 13-4-9
 * Time: 下午8:45
 */
public class HeartbeatThread extends Thread {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerFactory.Logger.game, HeartbeatThread.class);

    /**
     * 线程池1<br />
     * TODO：具体作用待补充
     */
    private final ExecutorService pool1;
    private final TimeService timeService;
    private final NormalSceneService normalSceneService;
    private final RepSceneService repSceneService;
    private final ArenaService arenaService;

    //    /**
//     * 是否繁忙
//     */
//    private volatile boolean isBusy;
    private volatile boolean started = false;

    private boolean isDebug = GameServerConfig.getInstance().isDebug();

    public HeartbeatThread(int threadNums, TimeService timeService, NormalSceneService normalSceneService, RepSceneService repSceneService,
                           ArenaService arenaService) {
        this.pool1 = Executors.newFixedThreadPool(threadNums, new NamedThreadFactory(getClass()));
        this.timeService = timeService;
        this.normalSceneService = normalSceneService;
        this.repSceneService = repSceneService;
        this.arenaService = arenaService;
    }

    /**
     * 启动
     */
    @Override
    public void start() {
        LOGGER.info("[start] [HeartbeatThread start begin].");
        // 设置开始标记
        started = true;
        // 调用父方法
        super.start();
        LOGGER.info("[start] [HeartbeatThread start success].");
    }

    @Override
    public void run() {
        try {
            while (started) {
                // 更新时间管理器
                timeService.update();
                // 遍历普通场景Runner
                List<SceneRunner<NormalScene>> sceneRunners = normalSceneService.getAllSceneRunners();
                for (SceneRunner<NormalScene> sceneRunner : sceneRunners) {
                    if (sceneRunner.isDone()) {
                        Future<Integer> newFuture = pool1.submit(sceneRunner);
                        sceneRunner.setFuture(newFuture);
                    }
                }
                // 遍历副本场景Runner
                List<SceneRunner<RepScene>> repRunners = repSceneService.getAllSceneRunners();
                for (SceneRunner<RepScene> repRunner : repRunners) {
                    if (repRunner.isDone()) {
                        Future<Integer> newFuture = pool1.submit(repRunner);
                        repRunner.setFuture(newFuture);
                    }
                }
                // 竞技场Runner
                ArenaRunner arenaRunner = arenaService.getRunner();
                if (arenaRunner.isDone()) {
                    Future<Void> newFuture = pool1.submit(arenaRunner);
                    arenaRunner.setFuture(newFuture);
                }

                // 心跳Sleep
                sleep(SharedConstants.GS_HEART_BEAT_INTERVAL);
                // 检查下是否有场景Runner还未执行好，理论来说，应该都执行好了。
//                isBusy = false;
                for (SceneRunner sceneRunner : sceneRunners) {
                    if (!sceneRunner.isDone()) {
//                        isBusy = true;
                        if (!isDebug) {
                            AbstractScene scene = sceneRunner.getScene();
                            LOGGER.error("[run] [scene:{}_{} is busy].", scene.getSceneId(), scene.getLine());
                        }
                    }
                }
                for (SceneRunner sceneRunner : repRunners) {
                    if (!sceneRunner.isDone()) {
//                        isBusy = true;
                        if (!isDebug) {
                            AbstractScene scene = sceneRunner.getScene();
                            LOGGER.error("[run] [scene:{}_{} is busy].", scene.getSceneId(), scene.getLine());
                        }
                    }
                }

                // WorldRunner

                // TODO 以后修正下
                BeanManager.getBean(IdSequenceDataUpdater.class).process();
            }

        } catch (Exception e) {
            // TODO 心跳出现异常如何处理
            e.printStackTrace();
        }
    }

    /**
     * 停止
     */
    public void shutdown() {
        LOGGER.info("[shutdown] [HeartbeatThread shutdown begin].");

        // 设置开始标记为false
        started = false;
        // 停止线程池
        ExecutorUtils.shutdownAndAwaitTermination(pool1);

        LOGGER.info("[shutdown] [HeartbeatThread shutdown success].");
    }
}
